# -*- coding: utf-8 -*-
from scrapy import Request
from scrapy.exceptions import IgnoreRequest
from scrapy.utils.project import get_project_settings
from zc_core.util.http_util import retry_request
from zc_core.spiders.base import BaseSpider
from ctaxccgp.rules import *


class SkuSpider(BaseSpider):
    name = 'sku'
    # 常用链接
    # suppliers_url = 'https://ctaxccgp.zcygov.cn/pages/suppliers'
    suppliers_url = 'https://ctaxccgp.zcygov.cn/front/index/search/supplier'
    sku_list_url = 'https://ctaxccgp.zcygov.cn/front/index/search/search'

    custom_settings = {
        'DOWNLOADER_MIDDLEWARES': {
            'ctaxccgp.middlewares.ZcySkuMiddleware': 740,
            'zc_core.middlewares.proxy.ProxyMiddleware': 650,
            'zc_core.middlewares.agent.UserAgentMiddleware': 640,
            'ctaxccgp.validator.BizValidator': 500
        }
    }

    def __init__(self, batchNo=None, *args, **kwargs):
        super(SkuSpider, self).__init__(batchNo=batchNo, *args, **kwargs)
        settings = get_project_settings()
        self.ladders = settings.get('PRICE_LADDER', [])
        self.page_size = 100
        self.max_page_limit = math.ceil(10000 / self.page_size)

    def start_requests(self):
        # 首页分类
        yield Request(
            url=self.suppliers_url,
            method='POST',
            body=json.dumps({
                "pageNo": 1,
                "pageSize": 100,
                "groupInstanceCodes": [],
                "groupTags": []
            }),
            meta={
                'reqType': 'supplier',
                'batchNo': self.batch_no,
            },
            headers={
                'Connection': 'keep-alive',
                'Cache-Control': 'max-age=0',
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/json;charset=UTF-8',
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                'Accept-Encoding': 'gzip, deflate, br',
                'Accept-Language': 'zh-CN,zh;q=0.9',
                'Cookie': 'districtCode=001000',
            },
            callback=self.parse_supplier,
            errback=self.error_back,
        )

    # 处理首页品类列表
    def parse_supplier(self, response):
        # 处理供应商列表
        sp_list = parse_supplier(response)
        if sp_list:
            self.logger.info('供应商: count[%s]' % len(sp_list))
            yield Box('supplier', self.batch_no, sp_list)

            for sp in sp_list:
                sp_id = sp.get('id')
                sp_name = sp.get('name')
                if self.ladders and sp_id:
                    for idx in range(1, len(self.ladders)):
                        page = 1
                        start_price = self.ladders[idx - 1] * 100
                        # 冗余
                        end_price = (self.ladders[idx] + 1) * 100
                        yield Request(
                            method='POST',
                            url=self.sku_list_url,
                            body=json.dumps({
                                'pageNo': page,
                                'pageSize': self.page_size,
                                'hasStock': False,
                                'searchType': 1,
                                'shopId': sp_id,
                                'deliveryCode': 110105,
                                'normal': 6,
                                'instanceCode': 'GSWC',
                                'p_f': start_price,
                                'p_t': end_price
                            }),
                            meta={
                                'reqType': 'sku',
                                'batchNo': self.batch_no,
                                'page': page,
                                'supplierId': sp_id,
                                'supplierName': sp_name,
                                'startPrice': start_price,
                                'endPrice': end_price,
                            },
                            headers={
                                'Connection': 'keep-alive',
                                'Cache-Control': 'max-age=0',
                                'X-Requested-With': 'XMLHttpRequest',
                                'Content-Type': 'application/json;charset=UTF-8',
                                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                                'Accept-Encoding': 'gzip, deflate, br',
                                'Accept-Language': 'zh-CN,zh;q=0.9',
                            },
                            callback=self.parse_sku_page,
                            errback=self.error_back,
                            priority=50,
                            dont_filter=True
                        )
        else:
            self.logger.info('无供应商')

    # 处理sku列表页数
    def parse_sku_page(self, response):
        meta = response.meta
        sp_id = meta.get('supplierId')
        sp_name = meta.get('supplierName')
        cur_page = meta.get('page')
        start_price = meta.get('startPrice')
        end_price = meta.get('endPrice')

        sku_list = parse_sku(response)
        if sku_list:
            self.logger.info(
                '清单: sp=%s, price=<%s, %s>, page=%s, cnt=%s' % (sp_id, start_price, end_price, cur_page, len(sku_list)))
            yield Box('sku', self.batch_no, sku_list)

            # 有更多页，并发请求
            if cur_page == 1 and len(sku_list) >= self.page_size:
                total_page = parse_sku_page(response, self.page_size)
                if total_page:
                    if total_page > self.max_page_limit:
                        self.logger.error(
                            '页数超限: sp=%s, start=%s, end=%s, total=%s' % (sp_id, start_price, end_price, total_page))
                    self.logger.info(
                        '页数: sp=%s, start=%s, end=%s, total=%s' % (sp_id, start_price, end_price, total_page))
                    for page in range(2, total_page + 1):
                        yield Request(
                            method='POST',
                            url=self.sku_list_url,
                            body=json.dumps({
                                'pageNo': page,
                                'pageSize': self.page_size,
                                'hasStock': False,
                                'searchType': 1,
                                'shopId': sp_id,
                                'deliveryCode': 110105,
                                'normal': 6,
                                'instanceCode': 'GSWC',
                                'p_f': start_price,
                                'p_t': end_price
                            }),
                            meta={
                                'reqType': 'sku',
                                'batchNo': self.batch_no,
                                'page': page,
                                'supplierId': sp_id,
                                'supplierName': sp_name,
                                'startPrice': start_price,
                                'endPrice': end_price,
                            },
                            headers={
                                'Connection': 'keep-alive',
                                'Cache-Control': 'max-age=0',
                                'X-Requested-With': 'XMLHttpRequest',
                                'Content-Type': 'application/json;charset=UTF-8',
                                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                                'Accept-Encoding': 'gzip, deflate, br',
                                'Accept-Language': 'zh-CN,zh;q=0.9',
                            },
                            callback=self.parse_sku_page,
                            errback=self.error_back,
                            priority=50,
                            dont_filter=True
                        )
        else:
            self.logger.info('无商品: sp=%s, price=<%s, %s>, page=%s' % (sp_id, start_price, end_price, cur_page))
